package com.hpf.community.aspect;

import com.hpf.community.annotations.MonitorLog;
import com.hpf.community.enums.LogEnum;
import com.hpf.community.model.LogModel;
import com.hpf.community.service.ILogService;
import com.hpf.community.utils.CommonUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @Author: hpf
 * @Date: 2020/4/18 19:26
 */
@Aspect
@Component
public class LogAsp {

    @Autowired
    private ILogService logService;

    /* *
     * @Author
     * <p> 设置切点</p>
     * @Param []
     * @Return void
     */
    @Pointcut("@annotation(com.hpf.community.annotations.MonitorLog)")
    public void logPointCut() {

    }

    // 环绕通知
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        // 开始时间
        LocalDateTime beginTime = LocalDateTime.now();
        // 执行方法
        Object result = point.proceed();
        // 结束时间
        LocalDateTime endTime = LocalDateTime.now();
        Duration duration = Duration.between(beginTime, endTime);
        // 操作时长
        long seconds = duration.getSeconds();
        // 保存日志
        saveLog(point,seconds);
        return result;
    }

    private void  saveLog(ProceedingJoinPoint point, long seconds){
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        // 获得注解
        MonitorLog monitorLog = method.getAnnotation(MonitorLog.class);
        if (monitorLog!=null){
            // 获得操作类型
            LogEnum operateType = monitorLog.operateType();
            // 获得操作内容
            String value = monitorLog.value();
//            System.out.printf("获得操作类型: %s , 获得操作内容: %s ",operateType.getCode(),value);
            //往数据库插入数据
            LogModel log = new LogModel();
            log.setId(CommonUtils.getUUID());
            log.setCreateDatetime(new Date());
            //请求的参数
            Object[] args = point.getArgs();
            try{
                List<Object> objects = Arrays.asList(args);
                log.setDescription(value);
                log.setArgs(objects.toString());
                if(StringUtils.isNotBlank(CommonUtils.getCurrentUserId())){
                    log.setCreateUserid(CommonUtils.getCurrentUserId());
                    log.setCreateUsername(CommonUtils.getCurrentUserName());
                    logService.insert(log);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
